package com.swak.http;

import javax.net.ssl.SSLException;

import org.asynchttpclient.AsyncHttpClientConfig;
import org.asynchttpclient.DefaultAsyncHttpClient;
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
import org.asynchttpclient.DefaultAsyncHttpClientConfig.Builder;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.util.Assert;

import com.swak.http.builder.RequestBuilder;
import com.swak.http.retry.RetryService;

import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.ssl.SslContext;
import lombok.Setter;

/**
 * Http 服务
 * 
 * @author lifeng
 */
public class HttpService implements DisposableBean {

	/**
	 * 使用的客户端 -- 线程安全
	 */
	private AsyncHttpClientConfig config;
	private DefaultAsyncHttpClient client;
	private RetryService retryService;

	/**
	 * 个性化参数
	 */
	@Setter
	private int connectTimeout = 60000;
	@Setter
	private int requestTimeout = 60000;
	@Setter
	private int readTimeout = 60000;

	/**
	 * 注册关闭函数
	 */
	public HttpService(AsyncHttpClientConfig config, RetryService retryService) {
		this.config = config;
		this.retryService = retryService;
		this.connectTimeout = config.getConnectTimeout();
		this.requestTimeout = config.getRequestTimeout();
		this.readTimeout = config.getReadTimeout();
	}

	/**
	 * 通过配置创建 Http服务
	 * 
	 * @param config
	 * @return
	 */
	public HttpService start() {
		Builder builder = new DefaultAsyncHttpClientConfig.Builder(config);
		builder.setConnectTimeout(connectTimeout).setReadTimeout(readTimeout).setRequestTimeout(requestTimeout);
		this.client = new DefaultAsyncHttpClient(builder.build());
		return this;
	}
	
	/**
	 * 通过配置创建 Http服务
	 * 
	 * @param config
	 * @return
	 */
	public HttpService start(SslContext sslContext) {
		Builder builder = new DefaultAsyncHttpClientConfig.Builder(config);
		builder.setConnectTimeout(connectTimeout).setReadTimeout(readTimeout).setRequestTimeout(requestTimeout);
		builder.setSslContext(sslContext);
		this.client = new DefaultAsyncHttpClient(builder.build());
		return this;
	}

	/**
	 * 通过配置创建 Http服务
	 * 
	 * @param config
	 * @return
	 * @throws SSLException
	 */
	public HttpService sslConfig(SslContext sslContext) throws RuntimeException {
		HttpService httpService = new HttpService(config, retryService);
		httpService.setConnectTimeout(connectTimeout);
		httpService.setReadTimeout(connectTimeout);
		httpService.setRequestTimeout(connectTimeout);
		return httpService.start(sslContext);
	}

	/**
	 * 创建一个builder
	 * 
	 * @return
	 */
	public RequestBuilder post() {
		Assert.isTrue(this.client != null, "Client Can Not Be Null");
		return new RequestBuilder(client, retryService).post();
	}

	/**
	 * 创建一个builder: 严格 json 格式的参数， 在body 中传递 json 数据
	 * 
	 * @return
	 */
	public RequestBuilder postJson() {
		Assert.isTrue(this.client != null, "Client Can Not Be Null");
		return new RequestBuilder(client, retryService).postJson();
	}

	/**
	 * 创建一个builder
	 * 
	 * @return
	 */
	public RequestBuilder get() {
		Assert.isTrue(this.client != null, "Client Can Not Be Null");
		return new RequestBuilder(client, retryService).get();
	}

	/**
	 * 创建一个builder
	 * 
	 * @return
	 */
	public RequestBuilder method(HttpMethod method) {
		Assert.isTrue(this.client != null, "Client Can Not Be Null");
		return new RequestBuilder(client, retryService).method(method);
	}

	@Override
	public void destroy() throws Exception {
		try {
			if (this.client != null) {
				this.client.close();
			}
		} catch (Exception e) {
		}
	}
}